package com.yfbao.horizon.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

public class LockUtils {

    private static final Logger log = LoggerFactory.getLogger(LockUtils.class);
    private static final Map<String, ReentrantLock> LOCK_MAP = new ConcurrentHashMap();

    public LockUtils() {
    }

    public static boolean tryLock(String lockName, long waitMillis) {
        boolean locked = false;
        ReentrantLock curLock = null;
        synchronized(LOCK_MAP) {
            curLock = (ReentrantLock)LOCK_MAP.get(lockName);
            if (curLock == null) {
                curLock = new ReentrantLock();
                LOCK_MAP.put(lockName, curLock);
            }
        }
        try {
            if (curLock != null) {
                locked = curLock.tryLock(waitMillis, TimeUnit.MILLISECONDS);
            }
        } catch (Exception var7) {
            log.error(var7.getMessage());
        }

        return locked;
    }

    public static void releaseLock(String lockName) {
        synchronized(LOCK_MAP) {
            ReentrantLock locklock = (ReentrantLock)LOCK_MAP.get(lockName);
            if (locklock != null) {
                locklock.unlock();
                if (locklock.getHoldCount() == 0) {
                    LOCK_MAP.remove(lockName);
                }
            }
        }
    }


    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(30);
        String key ="locke";
        for(int i=0;i<100;i++){
            int finalI = i;
            executorService.submit(()->{
                boolean lock = tryLock(key, 10);
                String name = Thread.currentThread().getName();
                if(lock){
                    System.out.println(name +" lockedSuccess");
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else {
                    System.out.println(name+" lockedfailed");
                }
//                if(lock){
                    try {
                        releaseLock(key);
                        System.out.println(name+" locked release");
                    }catch (Exception e){
                        System.out.println(e+":"+e.getMessage());
                    }
//                }
            });
        }
    }

}
